﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DA;
using BL;
using OrderDesk.Controllers;
using BaseLib.Localiztion;
using BL.Membership;

namespace OrderDesk.Areas.Admin.Controllers
{
    [AuthorizePage(UserPermission.UserManagement)]
    public class UsersController : BaseController
    {
        private UsersRepository rep = new UsersRepository();

        //
        // GET: /Admin/Categories/

        public ViewResult Index()
        {
            var users = rep.GetEntitySet();
            return View(users.ToList());
        }

        private IEnumerable<SelectListItem> GetRoles(User user)
        {
            RolesRepository rolesRepository = new RolesRepository();

            var roles =
                rolesRepository.GetEntitySet()
                .Select(x => new { x.RoleId, x.Name })
                .ToList()
                .Select(x => new SelectListItem { Value = x.RoleId.ToString(), Text = x.Name, Selected = false })
                .ToList();

            if (user != null)
            {
                var userRoles = user.GetRoles().Select(x => x.RoleId);

                foreach (var role in roles)
                {
                    role.Selected = userRoles.Contains(int.Parse(role.Value));
                }
            }

            return roles;
        }

        private IEnumerable<SelectListItem> GetPerms(User user)
        {
            Type userPermissionType = typeof(UserPermission);

            Client client = null;

            var clientPerms = UserPermission.None;
            if (user != null)
                client = user.Client;

            if (client == null)
                client = new ClientsRepository().GetEntity(CurrentUser.ClientId);

            clientPerms = client.GetPermissions();

            var userPerms = UserPermission.None;

            if (user != null)
                userPerms = user.GetUserPermissions();

            var permList =
                Enum.GetValues(userPermissionType)
                .Cast<UserPermission>()
                .Where(x =>
                    (x == UserPermission.SuperAdmin || clientPerms.HasFlag(x)) &&
                    x != UserPermission.None)
                .Select(x =>
                    new SelectListItem()
                    {
                        Value = ((long)x).ToString(),
                        Text = x.ToString(),
                        Selected = user != null ? userPerms.HasFlag(x) : false
                    });

            return permList;
        }

        public ActionResult Edit(int? id)
        {
            User user = null;
            if (id.HasValue)
                user = rep.GetEntity(id.Value, "Client");

            ViewBag.RoleList = GetRoles(user);
            ViewBag.PermList = GetPerms(user);

            if (this.IsClientsAdmin && !id.HasValue)
            {
                ViewBag.ClientId =
                    new ClientsRepository()
                    .GetEntitySet()
                    .ToList()
                    .Select(x => new SelectListItem() { Text = x.Name, Value = x.ClientId.ToString() });
            }

            return View(user);
        }
        public ActionResult ResetPassword(int id)
        {
            var user = rep.GetEntity(id);
            user.SetPassword("12345678");
            rep.Save(user);

            TempData["Message"] = Translator.Translate("pass_changed");
            return RedirectToAction("index");
        }
        public ActionResult ChangePassword(int id)
        {
            return View();
        }

        [HttpPost]
        public ActionResult ChangePassword(int id, string password, string confirmPassword)
        {
            if (password != confirmPassword)
            {
                ModelState.AddModelError("Password", Translator.Translate("err_pass_dont_match"));

                return View();
            }

            var user = rep.GetEntity(id);
            user.SetPassword(password);
            rep.Save(user);

            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult Edit(int? id, User model, FormCollection col)
        {
            User user;
            if (id.HasValue)
                user = rep.GetEntity(id.Value, "Client");
            else
                user = model;

            try
            {
                user.SetRoles(
                        col.AllKeys
                            .Where(x => x.StartsWith("role_") && col[x].ToLower().Contains("true"))
                            .Select(x => int.Parse(x.Substring("role_".Length)))
                            );

                var selectedPerms = col.AllKeys
                            .Where(x => x.StartsWith("perm_") && col[x].ToLower().Contains("true"))
                            .Select(x => (UserPermission)Enum.Parse(typeof(UserPermission), x.Substring("perm_".Length)));

                var perm = UserPermission.None;
                foreach (var currPerm in selectedPerms)
                {
                    perm |= currPerm;
                }

                user.SetPermissions(perm);
            }
            catch
            {
                ModelState.AddModelError("Roles", Translator.Translate("user_err_bad_roles"));
            }

            if (!ModelState.IsValid)
            {
                ViewBag.RoleList = GetRoles(user);
                ViewBag.PermList = GetPerms(user);

                if (this.IsClientsAdmin && !id.HasValue)
                {
                    ViewBag.ClientId =
                        new ClientsRepository()
                        .GetEntitySet()
                        .ToList()
                        .Select(x => new SelectListItem() { Text = x.Name, Value = x.ClientId.ToString() });
                }

                return View(model);
            }

            if (id.HasValue)
            {
                user.FirstName = model.FirstName;
                user.LastName = model.LastName;
                user.EMail = model.EMail;
            }

            user.ClientId = CurrentUser.ClientId;

            rep.Save(user);
            return RedirectToAction("Index");
        }

        //
        // GET: /Admin/Categories/Delete/5

        public ActionResult Delete(int id)
        {
            User user = rep.GetEntity(id);
            return View(user);
        }

        //
        // POST: /Admin/Categories/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            User user = rep.GetEntity(id);
            rep.Delete(user);

            return RedirectToAction("Index");
        }
    }
}